1 Read and Merge

Merge was succesful

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Derive new variables
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Data$D_VasS_Poz <- Data[, "VasS_postPoz"] - Data[, "VasS_prePoz"] 
Data$D_VasS_Neg <- Data[, "VasS_postNeg"] - Data[, "VasS_preNeg"]
Data$D_VasB_Poz <- Data[, "VasB_postPoz"] - Data[, "VasB_prePoz"] 
Data$D_VasB_Neg <- Data[, "VasB_postNeg"] - Data[, "VasB_preNeg"]
Data$D_IOS_Poz <- Data[, "IOS_postPoz"] - Data[, "IOS_prePoz"] 
Data$D_IOS_Neg <- Data[, "IOS_postNeg"] - Data[, "IOS_preNeg"]

Data$D_Sam1_Poz <- Data[, "Sam1_postPoz"] - Data[, "Sam1_prePoz"] 
Data$D_Sam1_Neg <- Data[, "Sam1_postNeg"] - Data[, "Sam1_preNeg"]
Data$D_Sam2_Poz <- Data[, "Sam2_postPoz"] - Data[, "Sam2_prePoz"] 
Data$D_Sam2_Neg <- Data[, "Sam2_postNeg"] - Data[, "Sam2_preNeg"]
Data$D_Sam3_Poz <- Data[, "Sam3_postPoz"] - Data[, "Sam3_prePoz"] 
Data$D_Sam3_Neg <- Data[, "Sam3_postNeg"] - Data[, "Sam3_preNeg"]

Data$D_DG_Poz <- Data[, "DG_postPozTot"] - Data[, "DG_prePozTot"] 
Data$D_DG_Neg <- Data[, "DG_postNegTot"] - Data[, "DG_preNegTot"]

Data$D_TrustMin_Poz <- Data[, "TrustMinPozPost"] - Data[, "TrustMinPozPre"] 
Data$D_TrustMin_Neg <- Data[, "TrustMinNegPost"] - Data[, "TrustMinNegPre"]
Data$D_TrustTot_Poz <- Data[, "TrustTotPozPost"] - Data[, "TrustTotPozPre"] 
Data$D_TrustTot_Neg <- Data[, "TrustTotNegPost"] - Data[, "TrustTotNegPre"]

Data$D_Cort_Poz <- Data[, "Cort_post_Poz"] - Data[, "Cort_pre_Poz"] 
Data$D_Cort_Neg <- Data[, "Cort_post_Neg"] - Data[, "Cort_pre_Neg"]
Data$D_Ox_Poz <- Data[, "Ox_post_Poz"] - Data[, "Ox_pre_Poz"] 
Data$D_Ox_Neg <- Data[, "Ox_post_Neg"] - Data[, "Ox_pre_Neg"]

–>

2 Define functions

# Define Function for Two-way rmANOVA
# library(tidyverse)
# library(ggpubr)
# library(rstatix)
# library(rlang)

tw_rmANOVA_func <- 
  function(data, id_var, cond_var, time_var, value_var, 
           assum_check = TRUE, posthoc_sig_interac = FALSE, posthoc_ns_interac = FALSE,
           p_adjust_method = "bonferroni"){
  
  # input dataframe needs to have columns names diffrent from "variable" and "value" because it collides with rstatix::shapiro_test
    
  id_var_enq <- rlang::enquo(id_var)  
  cond_var_enq <- rlang::enquo(cond_var)
  cond_var_name <- rlang::as_name(cond_var_enq)
  time_var_enq <- rlang::enquo(time_var)
  time_var_name <- rlang::as_name(time_var_enq)
  value_var_enq <- rlang::enquo(value_var)
  value_var_name <- rlang::as_name(value_var_enq)
    
  # Assumptions
  if(assum_check){
    cat("\n Outliers \n")
    data %>%
      dplyr::group_by(!!cond_var_enq, !!time_var_enq) %>%
      rstatix::identify_outliers(!!value_var_enq) %>%                                  # outliers (needs to be 0)
      print()
    
    cat("\n Normality assumption (p>.05) \n")
    data %>%
      dplyr::group_by(!!cond_var_enq, !!time_var_enq) %>%
      rstatix::shapiro_test(!!value_var_enq) %>%                                        # normality assumption (p>.05)
      print()
    
    qq_plot <- 
      ggpubr::ggqqplot(data = data, value_var_name, ggtheme = theme_bw(), title = "QQ Plot") +
        ggplot2::facet_grid(vars(!!time_var_enq), vars(!!cond_var_enq), labeller = "label_both")    # QQ plot
  }
  
  # Two-way rmANOVA - check for interaction (ex. F(2, 22) = 30.4, p < 0.0001)
  cat("\n Two-way rmANOVA \n")
  res_aov <- anova_test(                         # automatically does sphericity Mauchly’s test
    data = data, dv = !!value_var_enq, wid = !!id_var_enq,                             
    within = c(!!cond_var_enq, !!time_var_enq)
  )
  get_anova_table(res_aov) %>%  # ges: Greenhouse-Geisser sphericity correction is automatically applied to factors violating the sphericity assumption  
  print()
  
  #- Procedure for a significant two-way interaction -
  if(posthoc_sig_interac){
    cat("\n Effect of treatment at each time point \n")
    one_way <- 
      data %>%
      group_by(!!time_var_enq) %>%
      anova_test(dv = !!value_var_enq, wid = !!id_var_enq, within = !!cond_var_enq) %>%
      get_anova_table() %>%
      adjust_pvalue(method = "bonferroni")
    one_way %>% print()
    
    cat("\n Pairwise comparisons between treatment groups \n")
    pwc <-
      data %>%
      group_by(!!time_var_enq) %>%
      pairwise_t_test(
        as.formula(paste0(value_var_name, " ~ ", cond_var_name)),
        paired = TRUE,
        p.adjust.method = p_adjust_method
      )
    pwc %>% print()

    cat("\n Effect of time at each level of treatment - One-way ANOVA \n")
    one_way2 <-
      data %>%
      group_by(!!cond_var_enq) %>%
      anova_test(dv = !!value_var_enq, wid = !!id_var_enq, within = !!time_var_enq) %>%
      get_anova_table() %>%
      adjust_pvalue(method = p_adjust_method)
    one_way2  %>% print()
    cat("\n Pairwise comparisons between time points \n")
    pwc2 <-
      data %>%
      group_by(!!cond_var_enq) %>%
      pairwise_t_test(
        as.formula(paste0(value_var_name, " ~ ", time_var_name)),     # paste formula, not quosure
        paired = TRUE,
        p.adjust.method = p_adjust_method
      )
    pwc2  %>% print()
  }
  
  #- Procedure for non-significant two-way interaction- 
  # If the interaction is not significant, you need to interpret the main effects for each of the two variables: treatment and time.
  if(posthoc_ns_interac){
    cat("\n Comparisons for treatment variable \n")
    pwc_cond <-
      data %>%
      pairwise_t_test(
        as.formula(paste0(value_var_name, " ~ ", cond_var_name)),     # paste formula, not quosure             
        paired = TRUE,
        p.adjust.method = p_adjust_method
      )
    pwc_cond %>% print()
    cat("\n Comparisons for time variable \n")
    pwc_time <-
      data %>% 
      pairwise_t_test(
        as.formula(paste0(value_var_name, " ~ ", time_var_name)),     # paste formula, not quosure
        paired = TRUE,
        p.adjust.method = p_adjust_method
      )
    pwc_time %>% print()
  }
  
  # Visualization
  bx_plot <- 
    ggboxplot(data, x = time_var_name, y = value_var_name,
    color = cond_var_name, palette = "jco")
  pwc <- 
    pwc %>% 
    add_xy_position(x = time_var_name)
  bx_plot <- 
    bx_plot + 
    stat_pvalue_manual(pwc, tip.length = 0, hide.ns = TRUE) +
    labs(
      subtitle = get_test_label(res_aov, detailed = TRUE),
      caption = get_pwc_label(pwc)
    )
  
  if(assum_check){ 
    list(qq_plot, bx_plot)
  }else{
    bx_plot
  } 
  
}

# ex. - run on long format
# tw_rmANOVA_func(data = selfesteem2, id_var = id, cond_var = treatment, time_var = time, value_var = scores, 
#                 posthoc_sig_interac = TRUE, posthoc_ns_interac = TRUE)
## Wilcoxon signed rank test on paired samples

# library(tidyverse)
# library(ggpubr)
# library(rstatix)
# library(rlang)

wilcoxon_paired_func <- function(data, id_var, time_var, value_var, 
                                 assum_check = TRUE){
  
  id_var_enq <- rlang::enquo(id_var)  
  id_var_name <- rlang::as_name(id_var_enq)
  time_var_enq <- rlang::enquo(time_var)
  time_var_name <- rlang::as_name(time_var_enq)
  value_var_enq <- rlang::enquo(value_var)
  value_var_name <- rlang::as_name(value_var_enq)
  
  cat("\n Summary statistics \n")
  data %>%
    group_by(!!time_var_enq) %>%
    get_summary_stats(!!value_var_enq, type = c("common")) %>%
    print() 
  
  if(assum_check){  # The test assumes that differences between paired samples should be distributed symmetrically around the median.
  data2 <- 
    data %>% 
    group_by(!!id_var_enq) %>% 
    mutate(differences = !!value_var_enq - lag(!!value_var_enq))

  hist_dif_plot <- gghistogram(data2, x = "differences", y = "..density..", 
                               fill = "steelblue", add_density = TRUE)
  }
  
  cat("\n Wilcoxon signed rank test on paired samples \n")
  stat_test <- 
    data  %>%
    wilcox_test(as.formula(paste0(value_var_name, " ~ ", time_var_name)), 
                paired = TRUE) %>%
    add_significance()
  stat_test %>% print()
  
  cat("\n Effect size \n")
  ef_size <-
    data %>%
    wilcox_effsize(as.formula(paste0(value_var_name, " ~ ", time_var_name)), 
                   paired = TRUE)
  ef_size %>% print()
  
  # Visualization
  bx_plot <- ggpaired(data, x = time_var_name, y = value_var_name, id = id_var_name,
                      ylab = value_var_name, xlab = time_var_name)
  
  stat_test <- 
    stat_test %>% 
    add_xy_position(x = time_var_name)
  
  bx_plot <-
    bx_plot + 
      stat_pvalue_manual(stat_test, tip.length = 0) +
      labs(subtitle = get_test_label(stat_test, detailed = TRUE))
  
  if(assum_check){ 
    list(hist_dif_plot, bx_plot)
  }else{
    bx_plot
  }  
  
}

3 rmANOVA OXT

## All subjects

 Outliers 

 Normality assumption (p>.05) 

 Two-way rmANOVA 
ANOVA Table (type III tests)

        Effect DFn DFd      F        p p<.05   ges
1         Cond   1  28  0.537 0.470000       0.008
2      PrePost   1  28 17.388 0.000266     * 0.063
3 Cond:PrePost   1  28  0.220 0.642000       0.001

 Effect of treatment at each time point 

 Pairwise comparisons between treatment groups 

 Effect of time at each level of treatment - One-way ANOVA 

 Pairwise comparisons between time points 

 Comparisons for treatment variable 

 Comparisons for time variable 
[[1]]

[[2]]

## Females

 Outliers 

 Normality assumption (p>.05) 

 Two-way rmANOVA 
ANOVA Table (type III tests)

        Effect DFn DFd      F     p p<.05   ges
1         Cond   1  20  1.054 0.317       0.022
2      PrePost   1  20 10.660 0.004     * 0.055
3 Cond:PrePost   1  20  0.188 0.669       0.001

 Effect of treatment at each time point 

 Pairwise comparisons between treatment groups 

 Effect of time at each level of treatment - One-way ANOVA 

 Pairwise comparisons between time points 

 Comparisons for treatment variable 

 Comparisons for time variable 
[[1]]

[[2]]

## Males

 Outliers 

 Normality assumption (p>.05) 

 Two-way rmANOVA 
ANOVA Table (type III tests)

        Effect DFn DFd     F     p p<.05      ges
1         Cond   1   7 0.031 0.865       0.002000
2      PrePost   1   7 6.360 0.040     * 0.087000
3 Cond:PrePost   1   7 0.031 0.866       0.000557

 Effect of treatment at each time point 

 Pairwise comparisons between treatment groups 

 Effect of time at each level of treatment - One-way ANOVA 

 Pairwise comparisons between time points 

 Comparisons for treatment variable 

 Comparisons for time variable 
[[1]]

[[2]]

4 rmANOVA Stres

## All subjects

 Outliers 

 Normality assumption (p>.05) 

 Two-way rmANOVA 
ANOVA Table (type III tests)

        Effect DFn DFd     F     p p<.05       ges
1         Cond   1  29 0.004 0.949       0.0000565
2      PrePost   1  29 3.940 0.057       0.0060000
3 Cond:PrePost   1  29 4.259 0.048     * 0.0090000

 Effect of treatment at each time point 

 Pairwise comparisons between treatment groups 

 Effect of time at each level of treatment - One-way ANOVA 

 Pairwise comparisons between time points 

 Comparisons for treatment variable 

 Comparisons for time variable 
[[1]]

[[2]]

## Females

 Outliers 

 Normality assumption (p>.05) 

 Two-way rmANOVA 
ANOVA Table (type III tests)

        Effect DFn DFd     F     p p<.05      ges
1         Cond   1  21 0.014 0.907       0.000288
2      PrePost   1  21 1.407 0.249       0.003000
3 Cond:PrePost   1  21 5.206 0.033     * 0.017000

 Effect of treatment at each time point 

 Pairwise comparisons between treatment groups 

 Effect of time at each level of treatment - One-way ANOVA 

 Pairwise comparisons between time points 

 Comparisons for treatment variable 

 Comparisons for time variable 
[[1]]

[[2]]

## Males

 Outliers 

 Normality assumption (p>.05) 

 Two-way rmANOVA 
ANOVA Table (type III tests)

        Effect DFn DFd     F     p p<.05      ges
1         Cond   1   7 0.198 0.670       0.010000
2      PrePost   1   7 4.505 0.071       0.028000
3 Cond:PrePost   1   7 0.022 0.885       0.000121

 Effect of treatment at each time point 

 Pairwise comparisons between treatment groups 

 Effect of time at each level of treatment - One-way ANOVA 

 Pairwise comparisons between time points 

 Comparisons for treatment variable 

 Comparisons for time variable 
[[1]]

[[2]]

5 rmANOVA WB

## All subjects

 Outliers 

 Normality assumption (p>.05) 

 Two-way rmANOVA 
ANOVA Table (type III tests)

        Effect DFn DFd     F     p p<.05   ges
1         Cond   1  29 1.566 0.221       0.008
2      PrePost   1  29 2.072 0.161       0.003
3 Cond:PrePost   1  29 5.086 0.032     * 0.019

 Effect of treatment at each time point 

 Pairwise comparisons between treatment groups 

 Effect of time at each level of treatment - One-way ANOVA 

 Pairwise comparisons between time points 

 Comparisons for treatment variable 

 Comparisons for time variable 
[[1]]

[[2]]

## Females

 Outliers 

 Normality assumption (p>.05) 

 Two-way rmANOVA 
ANOVA Table (type III tests)

        Effect DFn DFd     F     p p<.05   ges
1         Cond   1  21 0.607 0.445       0.005
2      PrePost   1  21 0.850 0.367       0.003
3 Cond:PrePost   1  21 4.814 0.040     * 0.033

 Effect of treatment at each time point 

 Pairwise comparisons between treatment groups 

 Effect of time at each level of treatment - One-way ANOVA 

 Pairwise comparisons between time points 

 Comparisons for treatment variable 

 Comparisons for time variable 
[[1]]

[[2]]

## Males

 Outliers 

 Normality assumption (p>.05) 

 Two-way rmANOVA 
ANOVA Table (type III tests)

        Effect DFn DFd     F     p p<.05   ges
1         Cond   1   7 1.735 0.229       0.021
2      PrePost   1   7 5.885 0.046     * 0.007
3 Cond:PrePost   1   7 0.414 0.540       0.001

 Effect of treatment at each time point 

 Pairwise comparisons between treatment groups 

 Effect of time at each level of treatment - One-way ANOVA 

 Pairwise comparisons between time points 

 Comparisons for treatment variable 

 Comparisons for time variable 
[[1]]

[[2]]

6 Wilcoxon paired on Order of Conditions - OXT

## Whole Sample - Poz first, Neg second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

## Whole Sample - Neg first, Poz second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

## Females - Poz first, Neg second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

## Females - Neg first, Poz second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

7 Wilcoxon paired on Order of Conditions - Stres

## Whole Sample - Poz first, Neg second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

## Whole Sample - Neg first, Poz second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

## Females - Poz first, Neg second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

## Females - Neg first, Poz second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

8 Wilcoxon paired on Order of Conditions - WB

## Whole Sample - Poz first, Neg second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

## Whole Sample - Neg first, Poz second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

## Females - Poz first, Neg second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

## Females - Neg first, Poz second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]



9 Session Info

R version 3.6.1 (2019-07-05)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 8.1 x64 (build 9600)

Matrix products: default

locale:
[1] LC_COLLATE=Romanian_Romania.1250  LC_CTYPE=Romanian_Romania.1250    LC_MONETARY=Romanian_Romania.1250 LC_NUMERIC=C                     
[5] LC_TIME=Romanian_Romania.1250    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] rlang_0.4.6        rstatix_0.5.0      rio_0.5.16         summarytools_0.8.8 DT_0.5             ggpubr_0.2.5       magrittr_1.5       broom_0.5.6       
 [9] papaja_0.1.0.9842  psych_1.9.12.31    forcats_0.5.0      stringr_1.4.0      dplyr_0.8.5        purrr_0.3.3        readr_1.3.1        tidyr_1.0.2       
[17] tibble_3.0.0       ggplot2_3.3.0      tidyverse_1.3.0    pacman_0.5.1      

loaded via a namespace (and not attached):
 [1] nlme_3.1-140       bitops_1.0-6       matrixStats_0.54.0 fs_1.4.1           lubridate_1.7.4    httr_1.4.1         ggsci_2.9          tools_3.6.1       
 [9] backports_1.1.6    R6_2.4.1           DBI_1.0.0          colorspace_1.4-1   withr_2.1.2        tidyselect_1.0.0   mnormt_1.5-6       curl_4.3          
[17] compiler_3.6.1     cli_2.0.2          rvest_0.3.5        xml2_1.3.1         sandwich_2.5-0     labeling_0.3       scales_1.1.0       mvtnorm_1.1-0     
[25] digest_0.6.25      foreign_0.8-71     pkgconfig_2.0.3    htmltools_0.4.0    dbplyr_1.4.3       htmlwidgets_1.5.1  readxl_1.3.1       rstudioapi_0.11   
[33] pryr_0.1.4         generics_0.0.2     farver_2.0.3       zoo_1.8-4          jsonlite_1.6.1     zip_1.0.0          car_3.0-7          RCurl_1.95-4.11   
[41] modeltools_0.2-22  rapportools_1.0    Matrix_1.2-17      Rcpp_1.0.4.6       munsell_0.5.0      fansi_0.4.1        abind_1.4-5        lifecycle_0.2.0   
[49] multcomp_1.4-8     stringi_1.4.6      carData_3.0-2      MASS_7.3-51.4      plyr_1.8.6         grid_3.6.1         parallel_3.6.1     crayon_1.3.4      
[57] lattice_0.20-38    haven_2.2.0        splines_3.6.1      pander_0.6.3       hms_0.5.3          knitr_1.28         pillar_1.4.3       ggsignif_0.4.0    
[65] stats4_3.6.1       codetools_0.2-16   reprex_0.3.0       glue_1.4.0         data.table_1.12.8  modelr_0.1.6       vctrs_0.2.4        cellranger_1.1.0  
[73] gtable_0.3.0       assertthat_0.2.1   xfun_0.13          openxlsx_4.1.0     coin_1.2-2         survival_2.44-1.1  TH.data_1.0-9      ellipsis_0.3.0    
 

A work by Claudiu Papasteri

 

LS0tDQp0aXRsZTogIjxicj4gTy4yIFJlcG9ydCAtIEdlbmRlciIgDQpzdWJ0aXRsZTogIkZvY3VzIG9uIE9YVCBieSBHZW5kZXIiDQphdXRob3I6ICI8YnI+IENsYXVkaXUgUGFwYXN0ZXJpIg0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJW0gJVknKWAiDQpvdXRwdXQ6IA0KICAgIGh0bWxfbm90ZWJvb2s6DQogICAgICAgICAgIyBzZWxmX2NvbnRhaW5lZDogbm8NCiAgICAgICAgICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgICAgICAgICAgdG9jOiB0cnVlDQogICAgICAgICAgICB0b2NfZGVwdGg6IDINCiAgICAgICAgICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQ0KICAgICAgICAgICAgdGhlbWU6IHNwYWNlbGFiDQogICAgICAgICAgICBoaWdobGlnaHQ6IHRhbmdvDQogICAgICAgICAgICBmb250LWZhbWlseTogQXJpYWwNCiAgICAgICAgICAgIGZpZ193aWR0aDogMTANCiAgICAgICAgICAgIGZpZ19oZWlnaHQ6IDkNCiAgICAgIyBwZGZfZG9jdW1lbnQ6IA0KICAgICAgICAgICAgIyB0b2M6IHRydWUNCiAgICAgICAgICAgICMgdG9jX2RlcHRoOiAyDQogICAgICAgICAgICAjIG51bWJlcl9zZWN0aW9uczogdHJ1ZQ0KICAgICAgICAgICAgIyBmb250c2l6ZTogMTFwdA0KICAgICAgICAgICAgIyBnZW9tZXRyeTogbWFyZ2luPTFpbg0KICAgICAgICAgICAgIyBmaWdfd2lkdGg6IDcNCiAgICAgICAgICAgICMgZmlnX2hlaWdodDogNg0KICAgICAgICAgICAgIyBmaWdfY2FwdGlvbjogdHJ1ZQ0KICAgICMgZ2l0aHViX2RvY3VtZW50OiANCiAgICAgICAgICAgICMgdG9jOiB0cnVlDQogICAgICAgICAgICAjIHRvY19kZXB0aDogMg0KICAgICAgICAgICAgIyBodG1sX3ByZXZpZXc6IGZhbHNlDQogICAgICAgICAgICAjIGZpZ193aWR0aDogNQ0KICAgICAgICAgICAgIyBmaWdfaGVpZ2h0OiA1DQogICAgICAgICAgICAjIGRldjoganBlZw0KLS0tDQoNCg0KPCEtLSBTZXR1cCAtLT4NCg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMga2ludHIgb3B0aW9ucw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KA0KICBjb21tZW50ID0gIiMiLA0KICBjb2xsYXBzZSA9IFRSVUUsDQogIGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgY2FjaGUgPSBUUlVFICAgICAgICMgZWNobyA9IEZhbHNlIGZvciBnaXRodWJfZG9jdW1lbnQsIGJ1dCB3aWxsIGJlIGZvbGRlZCBpbiBodG1sX25vdGVib29rDQopDQoNCiMgR2VuZXJhbCBSIG9wdGlvbnMgYW5kIGluZm8NCnNldC5zZWVkKDExMSkgICAgICAgICAgICAgICAjIGluIGNhc2Ugd2UgdXNlIHJhbmRvbWl6ZWQgcHJvY2VkdXJlcyAgICAgICANCm9wdGlvbnMoc2NpcGVuID0gOTk5KSAgICAgICAjIHBvc2l0aXZlIHZhbHVlcyBiaWFzIHRvd2FyZHMgZml4ZWQgYW5kIG5lZ2F0aXZlIHRvd2FyZHMgc2NpZW50aWZpYyBub3RhdGlvbg0KDQojIExvYWQgcGFja2FnZXMNCmlmICghcmVxdWlyZSgicGFjbWFuIikpIGluc3RhbGwucGFja2FnZXMoInBhY21hbiIpDQpwYWNrYWdlcyA8LSBjKA0KICAidGlkeXZlcnNlIiwgICAgICAjIGJlc3QgdGhpbmcgdGhhdCBoYXBwZW5kIHRvIG1lDQogICJwc3ljaCIsICAgICAgICAgICMgZ2VuZXJhbCBwdXJwb3NlIHRvb2xib3ggZm9yIHBlcnNvbmFsaXR5LCBwc3ljaG9tZXRyaWMgdGhlb3J5IGFuZCBleHBlcmltZW50YWwgcHN5Y2hvbG9neQ0KICAicGFwYWphIiwgICAgICAgICAjIGZvciBBUEEgc3R5bGUNCiAgImJyb29tIiwgICAgICAgICAgIyBmb3IgdGlkeSBtb2RlbGxpbmcNCiAgImdncGxvdDIiLCAgICAgICAgIyBiZXN0IHBsb3RzDQogICJnZ3B1YnIiLCAgICAgICAgICMgZ2dwbG90MiB0byBwdWJsaWNhdGlvbiBxdWFsaXR5DQogICJEVCIsICAgICAgICAgICAgICMgbmljZSBzZWFyY2hhYmxlIGFuZCBkb3dubG9hZGFibGUgdGFibGVzDQogICJzdW1tYXJ5dG9vbHMiLA0KICAicmlvIiwNCiAgImdncHViciIsDQogICJyc3RhdGl4IiwNCiAgInJsYW5nIg0KICAjICwgLi4uDQopDQppZiAoIXJlcXVpcmUoInBhY21hbiIpKSBpbnN0YWxsLnBhY2thZ2VzKCJwYWNtYW4iKQ0KcGFjbWFuOjpwX2xvYWQoY2hhciA9IHBhY2thZ2VzKQ0KDQojIFRoZW1lcyBmb3IgZ2dwbG90MiBwbG90aW5nIChoZXJlIHVzZWQgQVBBIHN0eWxlKQ0KdGhlbWVfc2V0KHRoZW1lX2FwYSgpKQ0KYGBgDQoNCg0KDQo8IS0tIFJlcG9ydCAtLT4NCg0KDQojIFJlYWQgYW5kIE1lcmdlDQoNCg0KYGBge3IgcmVhZF9tZXJnZSwgcmVzdWx0cz0nYXNpcyd9DQojfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+DQojIFJlYWQgYW5kIE1lcmdlDQojfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+DQp3ZCA8LSAiRTovQ2luZXRpYyBpZGVpIG5vaS9FWFBFUklNRU5URSBPR0wgRnJvbnRpZXJzIChPLjIgJiBPLjAuMyAmIE8uMC4yKSINCnNldHdkKHdkKQ0KDQpEYXRhVHJ1c3QgPC0gcmlvOjppbXBvcnQoZmlsZS5wYXRoKHdkLCAiTy4yIFJFWlVMVEFURVxcTy4yIERhdGUgUHJlbHVjcmFyZVNQU1MgY3UgTkVPIHNpIFNUQUkiLCAiTy4yIERhdGUgcHQgVHJ1c3QgQlVOIGN1IE5FTyBzaSBTVEFJWS54bHN4IikpDQpEYXRhREcgPC0gcmlvOjppbXBvcnQoZmlsZS5wYXRoKHdkLCAiTy4yIFJFWlVMVEFURVxcTy4yIERhdGUgUHJlbHVjcmFyZVNQU1MgY3UgTkVPIHNpIFNUQUkiLCAiTy4yIERhdGUgcHQgREcgQlVOIGN1IE5FTyBzaSBTVEFJWS54bHN4IikpDQpEYXRhVkFTIDwtIHJpbzo6aW1wb3J0KGZpbGUucGF0aCh3ZCwgIk8uMiBSRVpVTFRBVEVcXE8uMiBWQVMsSU9TIiwgIk8uMiBEYXRlIFByZWx1Y3JhcmVTUFNTLnhsc3giKSkNCkRhdGFCSU8gPC0gcmlvOjppbXBvcnQoZmlsZS5wYXRoKHdkLCAiTy4yIEJJTyIsICJPLjIgT3ggc2kgQ29ydGl6b2wueGxzeCIpKQ0KICANCkRhdGFfbWVyZ2UxIDwtIG1lcmdlKERhdGFWQVMsIERhdGFUcnVzdCkgIA0KRGF0YV9tZXJnZTIgPC0gbWVyZ2UoRGF0YV9tZXJnZTEsIERhdGFERykgDQpEYXRhX21lcmdlMyA8LSBtZXJnZShEYXRhX21lcmdlMiwgRGF0YUJJTykNCg0KRGF0YSA8LSBEYXRhX21lcmdlMw0KDQp0ZXN0X25hbWVzIDwtIHVuaXF1ZSh1bmxpc3QobGFwcGx5KGxpc3QoRGF0YVRydXN0LCBEYXRhREcsIERhdGFWQVMsIERhdGFCSU8pLCBuYW1lcykpKQ0KbWVyZ2VfbmFtZXMgPC0gbmFtZXMoRGF0YSkNCg0KaWYoaWRlbnRpY2FsKG1lcmdlX25hbWVzW29yZGVyKG1lcmdlX25hbWVzKV0sIHRlc3RfbmFtZXNbb3JkZXIodGVzdF9uYW1lcyldKSl7ICAgICMgdGhlIG9yZGVyIG1hdHRlcnMgaW4gaWRlbnRpY2FsKCkNCiAgY2F0KCIqKk1lcmdlIHdhcyBzdWNjZXNmdWwqKiIpDQogIHJtKCJEYXRhX21lcmdlMSIsICJEYXRhX21lcmdlMiIsICJEYXRhX21lcmdlMyIsICJEYXRhQklPIiwgIkRhdGFERyIsICJEYXRhVHJ1c3QiLCAiRGF0YVZBUyIsICJ0ZXN0X25hbWVzIiwgIm1lcmdlX25hbWVzIikNCn1lbHNlIGNhdCgiKipNZXJnZSB1bnN1Y2Nlc2Z1bCoqIikgDQoNCg0KIyBHZW5kZXIgRGF0YWZyYW1lDQpEYXRhX0dlbiA8LSByaW86OmltcG9ydChmaWxlLnBhdGgod2QsICJHZW4gdmFyc3RhIE8wMyBPMDIgTzIueGxzeCIpLCB3aGljaCA9ICJPLjIiKQ0KDQpEYXRhX0dlbl9tZXJnZWQgPC0gDQogIERhdGEgJT4lDQogIHRpZHlyOjpzZXBhcmF0ZShJbmRpY2F0aXYsICBjKCJJRF90YWciLCAiSUQiLCAic3R1ZHlfdGFnIiksICJcXHMrIikgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgc3BsaXQgb24gd2hpdGUgc3BhY2UNCiAgc2VsZWN0KC1jKCJJRF90YWciLCAic3R1ZHlfdGFnIikpICU+JQ0KICBtdXRhdGUoSUQgPSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihJRCkpKSAlPiUNCiAgZHBseXI6OmxlZnRfam9pbiguLCBEYXRhX0dlbiwgYnkgPSBjKCJJRCIpKSAlPiUNCiAgc2VsZWN0KDE6NywgR2VuLCBWYXJzdGEsIGV2ZXJ5dGhpbmcoKSkNCg0KRGF0YV9HZW5fbWVyZ2VkX2xvbmcgPC0NCiAgRGF0YV9HZW5fbWVyZ2VkICU+JQ0KICBkcGx5cjo6c2VsZWN0KElELCBFeGVyY2l0aXVsLCBHZW4sIHN0YXJ0c193aXRoKCJWYXMiKSwgc3RhcnRzX3dpdGgoIk94IikpICU+JQ0KICBkcGx5cjo6cmVuYW1lKFZhc1NfcHJlX1BveiA9IFZhc1NfcHJlUG96LA0KICAgICAgICAgICAgICAgIFZhc0JfcHJlX1BveiA9IFZhc0JfcHJlUG96LA0KICAgICAgICAgICAgICAgIFZhc1NfcG9zdF9Qb3ogPSBWYXNTX3Bvc3RQb3osDQogICAgICAgICAgICAgICAgVmFzQl9wb3N0X1BveiA9IFZhc0JfcG9zdFBveiwNCiAgICAgICAgICAgICAgICBWYXNTX3ByZV9OZWcgPSBWYXNTX3ByZU5lZywNCiAgICAgICAgICAgICAgICBWYXNCX3ByZV9OZWcgPSBWYXNCX3ByZU5lZywNCiAgICAgICAgICAgICAgICBWYXNTX3Bvc3RfTmVnID0gVmFzU19wb3N0TmVnLA0KICAgICAgICAgICAgICAgIFZhc0JfcG9zdF9OZWcgPSBWYXNCX3Bvc3ROZWcpICU+JQ0KICBwaXZvdF9sb25nZXIoLWMoSUQsIEV4ZXJjaXRpdWwsIEdlbiksIG5hbWVzX3NlcCA9ICJfIiwgbmFtZXNfdG8gPSBjKCJWYXJzIiwgIlByZVBvc3QiLCAiQ29uZCIpLCB2YWx1ZXNfdG8gPSAiVmFscyIpICU+JQ0KICByc3RhdGl4Ojpjb252ZXJ0X2FzX2ZhY3RvcihJRCwgRXhlcmNpdGl1bCwgR2VuLCBWYXJzLCBQcmVQb3N0LCBDb25kKQ0KDQoNCg0KRGF0YV9mZW0gPC0gDQogIERhdGFfR2VuX21lcmdlZF9sb25nICU+JQ0KICBmaWx0ZXIoR2VuID09ICJGIikNCg0KRGF0YV9tYXNjIDwtIA0KICBEYXRhX0dlbl9tZXJnZWRfbG9uZyAlPiUNCiAgZmlsdGVyKEdlbiA9PSAiTSIpDQpgYGANCg0KPCEtLQ0KIyBEZXJpdmUgbmV3IHZhcmlhYmxlcw0KDQpgYGB7ciBkZXJpdmVfdmFyLCBoaWRlPVRSVUV9DQojfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+DQojIERlcml2ZSBuZXcgdmFyaWFibGVzDQojfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+DQpEYXRhJERfVmFzU19Qb3ogPC0gRGF0YVssICJWYXNTX3Bvc3RQb3oiXSAtIERhdGFbLCAiVmFzU19wcmVQb3oiXSANCkRhdGEkRF9WYXNTX05lZyA8LSBEYXRhWywgIlZhc1NfcG9zdE5lZyJdIC0gRGF0YVssICJWYXNTX3ByZU5lZyJdDQpEYXRhJERfVmFzQl9Qb3ogPC0gRGF0YVssICJWYXNCX3Bvc3RQb3oiXSAtIERhdGFbLCAiVmFzQl9wcmVQb3oiXSANCkRhdGEkRF9WYXNCX05lZyA8LSBEYXRhWywgIlZhc0JfcG9zdE5lZyJdIC0gRGF0YVssICJWYXNCX3ByZU5lZyJdDQpEYXRhJERfSU9TX1BveiA8LSBEYXRhWywgIklPU19wb3N0UG96Il0gLSBEYXRhWywgIklPU19wcmVQb3oiXSANCkRhdGEkRF9JT1NfTmVnIDwtIERhdGFbLCAiSU9TX3Bvc3ROZWciXSAtIERhdGFbLCAiSU9TX3ByZU5lZyJdDQoNCkRhdGEkRF9TYW0xX1BveiA8LSBEYXRhWywgIlNhbTFfcG9zdFBveiJdIC0gRGF0YVssICJTYW0xX3ByZVBveiJdIA0KRGF0YSREX1NhbTFfTmVnIDwtIERhdGFbLCAiU2FtMV9wb3N0TmVnIl0gLSBEYXRhWywgIlNhbTFfcHJlTmVnIl0NCkRhdGEkRF9TYW0yX1BveiA8LSBEYXRhWywgIlNhbTJfcG9zdFBveiJdIC0gRGF0YVssICJTYW0yX3ByZVBveiJdIA0KRGF0YSREX1NhbTJfTmVnIDwtIERhdGFbLCAiU2FtMl9wb3N0TmVnIl0gLSBEYXRhWywgIlNhbTJfcHJlTmVnIl0NCkRhdGEkRF9TYW0zX1BveiA8LSBEYXRhWywgIlNhbTNfcG9zdFBveiJdIC0gRGF0YVssICJTYW0zX3ByZVBveiJdIA0KRGF0YSREX1NhbTNfTmVnIDwtIERhdGFbLCAiU2FtM19wb3N0TmVnIl0gLSBEYXRhWywgIlNhbTNfcHJlTmVnIl0NCg0KRGF0YSREX0RHX1BveiA8LSBEYXRhWywgIkRHX3Bvc3RQb3pUb3QiXSAtIERhdGFbLCAiREdfcHJlUG96VG90Il0gDQpEYXRhJERfREdfTmVnIDwtIERhdGFbLCAiREdfcG9zdE5lZ1RvdCJdIC0gRGF0YVssICJER19wcmVOZWdUb3QiXQ0KDQpEYXRhJERfVHJ1c3RNaW5fUG96IDwtIERhdGFbLCAiVHJ1c3RNaW5Qb3pQb3N0Il0gLSBEYXRhWywgIlRydXN0TWluUG96UHJlIl0gDQpEYXRhJERfVHJ1c3RNaW5fTmVnIDwtIERhdGFbLCAiVHJ1c3RNaW5OZWdQb3N0Il0gLSBEYXRhWywgIlRydXN0TWluTmVnUHJlIl0NCkRhdGEkRF9UcnVzdFRvdF9Qb3ogPC0gRGF0YVssICJUcnVzdFRvdFBvelBvc3QiXSAtIERhdGFbLCAiVHJ1c3RUb3RQb3pQcmUiXSANCkRhdGEkRF9UcnVzdFRvdF9OZWcgPC0gRGF0YVssICJUcnVzdFRvdE5lZ1Bvc3QiXSAtIERhdGFbLCAiVHJ1c3RUb3ROZWdQcmUiXQ0KDQpEYXRhJERfQ29ydF9Qb3ogPC0gRGF0YVssICJDb3J0X3Bvc3RfUG96Il0gLSBEYXRhWywgIkNvcnRfcHJlX1BveiJdIA0KRGF0YSREX0NvcnRfTmVnIDwtIERhdGFbLCAiQ29ydF9wb3N0X05lZyJdIC0gRGF0YVssICJDb3J0X3ByZV9OZWciXQ0KRGF0YSREX094X1BveiA8LSBEYXRhWywgIk94X3Bvc3RfUG96Il0gLSBEYXRhWywgIk94X3ByZV9Qb3oiXSANCkRhdGEkRF9PeF9OZWcgPC0gRGF0YVssICJPeF9wb3N0X05lZyJdIC0gRGF0YVssICJPeF9wcmVfTmVnIl0NCmBgYA0KDQotLT4NCg0KIyBEZWZpbmUgZnVuY3Rpb25zDQoNCmBgYHtyIGRlZl9mdW5jX3JtQU5PVkF9DQojIERlZmluZSBGdW5jdGlvbiBmb3IgVHdvLXdheSBybUFOT1ZBDQojIGxpYnJhcnkodGlkeXZlcnNlKQ0KIyBsaWJyYXJ5KGdncHVicikNCiMgbGlicmFyeShyc3RhdGl4KQ0KIyBsaWJyYXJ5KHJsYW5nKQ0KDQp0d19ybUFOT1ZBX2Z1bmMgPC0gDQogIGZ1bmN0aW9uKGRhdGEsIGlkX3ZhciwgY29uZF92YXIsIHRpbWVfdmFyLCB2YWx1ZV92YXIsIA0KICAgICAgICAgICBhc3N1bV9jaGVjayA9IFRSVUUsIHBvc3Rob2Nfc2lnX2ludGVyYWMgPSBGQUxTRSwgcG9zdGhvY19uc19pbnRlcmFjID0gRkFMU0UsDQogICAgICAgICAgIHBfYWRqdXN0X21ldGhvZCA9ICJib25mZXJyb25pIil7DQogIA0KICAjIGlucHV0IGRhdGFmcmFtZSBuZWVkcyB0byBoYXZlIGNvbHVtbnMgbmFtZXMgZGlmZnJlbnQgZnJvbSAidmFyaWFibGUiIGFuZCAidmFsdWUiIGJlY2F1c2UgaXQgY29sbGlkZXMgd2l0aCByc3RhdGl4OjpzaGFwaXJvX3Rlc3QNCiAgICANCiAgaWRfdmFyX2VucSA8LSBybGFuZzo6ZW5xdW8oaWRfdmFyKSAgDQogIGNvbmRfdmFyX2VucSA8LSBybGFuZzo6ZW5xdW8oY29uZF92YXIpDQogIGNvbmRfdmFyX25hbWUgPC0gcmxhbmc6OmFzX25hbWUoY29uZF92YXJfZW5xKQ0KICB0aW1lX3Zhcl9lbnEgPC0gcmxhbmc6OmVucXVvKHRpbWVfdmFyKQ0KICB0aW1lX3Zhcl9uYW1lIDwtIHJsYW5nOjphc19uYW1lKHRpbWVfdmFyX2VucSkNCiAgdmFsdWVfdmFyX2VucSA8LSBybGFuZzo6ZW5xdW8odmFsdWVfdmFyKQ0KICB2YWx1ZV92YXJfbmFtZSA8LSBybGFuZzo6YXNfbmFtZSh2YWx1ZV92YXJfZW5xKQ0KICAgIA0KICAjIEFzc3VtcHRpb25zDQogIGlmKGFzc3VtX2NoZWNrKXsNCiAgICBjYXQoIlxuIE91dGxpZXJzIFxuIikNCiAgICBkYXRhICU+JQ0KICAgICAgZHBseXI6Omdyb3VwX2J5KCEhY29uZF92YXJfZW5xLCAhIXRpbWVfdmFyX2VucSkgJT4lDQogICAgICByc3RhdGl4OjppZGVudGlmeV9vdXRsaWVycyghIXZhbHVlX3Zhcl9lbnEpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIG91dGxpZXJzIChuZWVkcyB0byBiZSAwKQ0KICAgICAgcHJpbnQoKQ0KICAgIA0KICAgIGNhdCgiXG4gTm9ybWFsaXR5IGFzc3VtcHRpb24gKHA+LjA1KSBcbiIpDQogICAgZGF0YSAlPiUNCiAgICAgIGRwbHlyOjpncm91cF9ieSghIWNvbmRfdmFyX2VucSwgISF0aW1lX3Zhcl9lbnEpICU+JQ0KICAgICAgcnN0YXRpeDo6c2hhcGlyb190ZXN0KCEhdmFsdWVfdmFyX2VucSkgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbm9ybWFsaXR5IGFzc3VtcHRpb24gKHA+LjA1KQ0KICAgICAgcHJpbnQoKQ0KICAgIA0KICAgIHFxX3Bsb3QgPC0gDQogICAgICBnZ3B1YnI6OmdncXFwbG90KGRhdGEgPSBkYXRhLCB2YWx1ZV92YXJfbmFtZSwgZ2d0aGVtZSA9IHRoZW1lX2J3KCksIHRpdGxlID0gIlFRIFBsb3QiKSArDQogICAgICAgIGdncGxvdDI6OmZhY2V0X2dyaWQodmFycyghIXRpbWVfdmFyX2VucSksIHZhcnMoISFjb25kX3Zhcl9lbnEpLCBsYWJlbGxlciA9ICJsYWJlbF9ib3RoIikgICAgIyBRUSBwbG90DQogIH0NCiAgDQogICMgVHdvLXdheSBybUFOT1ZBIC0gY2hlY2sgZm9yIGludGVyYWN0aW9uIChleC4gRigyLCAyMikgPSAzMC40LCBwIDwgMC4wMDAxKQ0KICBjYXQoIlxuIFR3by13YXkgcm1BTk9WQSBcbiIpDQogIHJlc19hb3YgPC0gYW5vdmFfdGVzdCggICAgICAgICAgICAgICAgICAgICAgICAgIyBhdXRvbWF0aWNhbGx5IGRvZXMgc3BoZXJpY2l0eSBNYXVjaGx54oCZcyB0ZXN0DQogICAgZGF0YSA9IGRhdGEsIGR2ID0gISF2YWx1ZV92YXJfZW5xLCB3aWQgPSAhIWlkX3Zhcl9lbnEsICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICB3aXRoaW4gPSBjKCEhY29uZF92YXJfZW5xLCAhIXRpbWVfdmFyX2VucSkNCiAgKQ0KICBnZXRfYW5vdmFfdGFibGUocmVzX2FvdikgJT4lICAjIGdlczogR3JlZW5ob3VzZS1HZWlzc2VyIHNwaGVyaWNpdHkgY29ycmVjdGlvbiBpcyBhdXRvbWF0aWNhbGx5IGFwcGxpZWQgdG8gZmFjdG9ycyB2aW9sYXRpbmcgdGhlIHNwaGVyaWNpdHkgYXNzdW1wdGlvbiAgDQogIHByaW50KCkNCiAgDQogICMtIFByb2NlZHVyZSBmb3IgYSBzaWduaWZpY2FudCB0d28td2F5IGludGVyYWN0aW9uIC0NCiAgaWYocG9zdGhvY19zaWdfaW50ZXJhYyl7DQogICAgY2F0KCJcbiBFZmZlY3Qgb2YgdHJlYXRtZW50IGF0IGVhY2ggdGltZSBwb2ludCBcbiIpDQogICAgb25lX3dheSA8LSANCiAgICAgIGRhdGEgJT4lDQogICAgICBncm91cF9ieSghIXRpbWVfdmFyX2VucSkgJT4lDQogICAgICBhbm92YV90ZXN0KGR2ID0gISF2YWx1ZV92YXJfZW5xLCB3aWQgPSAhIWlkX3Zhcl9lbnEsIHdpdGhpbiA9ICEhY29uZF92YXJfZW5xKSAlPiUNCiAgICAgIGdldF9hbm92YV90YWJsZSgpICU+JQ0KICAgICAgYWRqdXN0X3B2YWx1ZShtZXRob2QgPSAiYm9uZmVycm9uaSIpDQogICAgb25lX3dheSAlPiUgcHJpbnQoKQ0KICAgIA0KICAgIGNhdCgiXG4gUGFpcndpc2UgY29tcGFyaXNvbnMgYmV0d2VlbiB0cmVhdG1lbnQgZ3JvdXBzIFxuIikNCiAgICBwd2MgPC0NCiAgICAgIGRhdGEgJT4lDQogICAgICBncm91cF9ieSghIXRpbWVfdmFyX2VucSkgJT4lDQogICAgICBwYWlyd2lzZV90X3Rlc3QoDQogICAgICAgIGFzLmZvcm11bGEocGFzdGUwKHZhbHVlX3Zhcl9uYW1lLCAiIH4gIiwgY29uZF92YXJfbmFtZSkpLA0KICAgICAgICBwYWlyZWQgPSBUUlVFLA0KICAgICAgICBwLmFkanVzdC5tZXRob2QgPSBwX2FkanVzdF9tZXRob2QNCiAgICAgICkNCiAgICBwd2MgJT4lIHByaW50KCkNCg0KICAgIGNhdCgiXG4gRWZmZWN0IG9mIHRpbWUgYXQgZWFjaCBsZXZlbCBvZiB0cmVhdG1lbnQgLSBPbmUtd2F5IEFOT1ZBIFxuIikNCiAgICBvbmVfd2F5MiA8LQ0KICAgICAgZGF0YSAlPiUNCiAgICAgIGdyb3VwX2J5KCEhY29uZF92YXJfZW5xKSAlPiUNCiAgICAgIGFub3ZhX3Rlc3QoZHYgPSAhIXZhbHVlX3Zhcl9lbnEsIHdpZCA9ICEhaWRfdmFyX2VucSwgd2l0aGluID0gISF0aW1lX3Zhcl9lbnEpICU+JQ0KICAgICAgZ2V0X2Fub3ZhX3RhYmxlKCkgJT4lDQogICAgICBhZGp1c3RfcHZhbHVlKG1ldGhvZCA9IHBfYWRqdXN0X21ldGhvZCkNCiAgICBvbmVfd2F5MiAgJT4lIHByaW50KCkNCiAgICBjYXQoIlxuIFBhaXJ3aXNlIGNvbXBhcmlzb25zIGJldHdlZW4gdGltZSBwb2ludHMgXG4iKQ0KICAgIHB3YzIgPC0NCiAgICAgIGRhdGEgJT4lDQogICAgICBncm91cF9ieSghIWNvbmRfdmFyX2VucSkgJT4lDQogICAgICBwYWlyd2lzZV90X3Rlc3QoDQogICAgICAgIGFzLmZvcm11bGEocGFzdGUwKHZhbHVlX3Zhcl9uYW1lLCAiIH4gIiwgdGltZV92YXJfbmFtZSkpLCAgICAgIyBwYXN0ZSBmb3JtdWxhLCBub3QgcXVvc3VyZQ0KICAgICAgICBwYWlyZWQgPSBUUlVFLA0KICAgICAgICBwLmFkanVzdC5tZXRob2QgPSBwX2FkanVzdF9tZXRob2QNCiAgICAgICkNCiAgICBwd2MyICAlPiUgcHJpbnQoKQ0KICB9DQogIA0KICAjLSBQcm9jZWR1cmUgZm9yIG5vbi1zaWduaWZpY2FudCB0d28td2F5IGludGVyYWN0aW9uLSANCiAgIyBJZiB0aGUgaW50ZXJhY3Rpb24gaXMgbm90IHNpZ25pZmljYW50LCB5b3UgbmVlZCB0byBpbnRlcnByZXQgdGhlIG1haW4gZWZmZWN0cyBmb3IgZWFjaCBvZiB0aGUgdHdvIHZhcmlhYmxlczogdHJlYXRtZW50IGFuZCB0aW1lLg0KICBpZihwb3N0aG9jX25zX2ludGVyYWMpew0KICAgIGNhdCgiXG4gQ29tcGFyaXNvbnMgZm9yIHRyZWF0bWVudCB2YXJpYWJsZSBcbiIpDQogICAgcHdjX2NvbmQgPC0NCiAgICAgIGRhdGEgJT4lDQogICAgICBwYWlyd2lzZV90X3Rlc3QoDQogICAgICAgIGFzLmZvcm11bGEocGFzdGUwKHZhbHVlX3Zhcl9uYW1lLCAiIH4gIiwgY29uZF92YXJfbmFtZSkpLCAgICAgIyBwYXN0ZSBmb3JtdWxhLCBub3QgcXVvc3VyZSAgICAgICAgICAgICANCiAgICAgICAgcGFpcmVkID0gVFJVRSwNCiAgICAgICAgcC5hZGp1c3QubWV0aG9kID0gcF9hZGp1c3RfbWV0aG9kDQogICAgICApDQogICAgcHdjX2NvbmQgJT4lIHByaW50KCkNCiAgICBjYXQoIlxuIENvbXBhcmlzb25zIGZvciB0aW1lIHZhcmlhYmxlIFxuIikNCiAgICBwd2NfdGltZSA8LQ0KICAgICAgZGF0YSAlPiUgDQogICAgICBwYWlyd2lzZV90X3Rlc3QoDQogICAgICAgIGFzLmZvcm11bGEocGFzdGUwKHZhbHVlX3Zhcl9uYW1lLCAiIH4gIiwgdGltZV92YXJfbmFtZSkpLCAgICAgIyBwYXN0ZSBmb3JtdWxhLCBub3QgcXVvc3VyZQ0KICAgICAgICBwYWlyZWQgPSBUUlVFLA0KICAgICAgICBwLmFkanVzdC5tZXRob2QgPSBwX2FkanVzdF9tZXRob2QNCiAgICAgICkNCiAgICBwd2NfdGltZSAlPiUgcHJpbnQoKQ0KICB9DQogIA0KICAjIFZpc3VhbGl6YXRpb24NCiAgYnhfcGxvdCA8LSANCiAgICBnZ2JveHBsb3QoZGF0YSwgeCA9IHRpbWVfdmFyX25hbWUsIHkgPSB2YWx1ZV92YXJfbmFtZSwNCiAgICBjb2xvciA9IGNvbmRfdmFyX25hbWUsIHBhbGV0dGUgPSAiamNvIikNCiAgcHdjIDwtIA0KICAgIHB3YyAlPiUgDQogICAgYWRkX3h5X3Bvc2l0aW9uKHggPSB0aW1lX3Zhcl9uYW1lKQ0KICBieF9wbG90IDwtIA0KICAgIGJ4X3Bsb3QgKyANCiAgICBzdGF0X3B2YWx1ZV9tYW51YWwocHdjLCB0aXAubGVuZ3RoID0gMCwgaGlkZS5ucyA9IFRSVUUpICsNCiAgICBsYWJzKA0KICAgICAgc3VidGl0bGUgPSBnZXRfdGVzdF9sYWJlbChyZXNfYW92LCBkZXRhaWxlZCA9IFRSVUUpLA0KICAgICAgY2FwdGlvbiA9IGdldF9wd2NfbGFiZWwocHdjKQ0KICAgICkNCiAgDQogIGlmKGFzc3VtX2NoZWNrKXsgDQogICAgbGlzdChxcV9wbG90LCBieF9wbG90KQ0KICB9ZWxzZXsNCiAgICBieF9wbG90DQogIH0gDQogIA0KfQ0KDQojIGV4LiAtIHJ1biBvbiBsb25nIGZvcm1hdA0KIyB0d19ybUFOT1ZBX2Z1bmMoZGF0YSA9IHNlbGZlc3RlZW0yLCBpZF92YXIgPSBpZCwgY29uZF92YXIgPSB0cmVhdG1lbnQsIHRpbWVfdmFyID0gdGltZSwgdmFsdWVfdmFyID0gc2NvcmVzLCANCiMgICAgICAgICAgICAgICAgIHBvc3Rob2Nfc2lnX2ludGVyYWMgPSBUUlVFLCBwb3N0aG9jX25zX2ludGVyYWMgPSBUUlVFKQ0KDQpgYGANCg0KYGBge3IgZGVmX2Z1bmNfV2lsY294b25wYWlyZWR9DQojIyBXaWxjb3hvbiBzaWduZWQgcmFuayB0ZXN0IG9uIHBhaXJlZCBzYW1wbGVzDQoNCiMgbGlicmFyeSh0aWR5dmVyc2UpDQojIGxpYnJhcnkoZ2dwdWJyKQ0KIyBsaWJyYXJ5KHJzdGF0aXgpDQojIGxpYnJhcnkocmxhbmcpDQoNCndpbGNveG9uX3BhaXJlZF9mdW5jIDwtIGZ1bmN0aW9uKGRhdGEsIGlkX3ZhciwgdGltZV92YXIsIHZhbHVlX3ZhciwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3N1bV9jaGVjayA9IFRSVUUpew0KICANCiAgaWRfdmFyX2VucSA8LSBybGFuZzo6ZW5xdW8oaWRfdmFyKSAgDQogIGlkX3Zhcl9uYW1lIDwtIHJsYW5nOjphc19uYW1lKGlkX3Zhcl9lbnEpDQogIHRpbWVfdmFyX2VucSA8LSBybGFuZzo6ZW5xdW8odGltZV92YXIpDQogIHRpbWVfdmFyX25hbWUgPC0gcmxhbmc6OmFzX25hbWUodGltZV92YXJfZW5xKQ0KICB2YWx1ZV92YXJfZW5xIDwtIHJsYW5nOjplbnF1byh2YWx1ZV92YXIpDQogIHZhbHVlX3Zhcl9uYW1lIDwtIHJsYW5nOjphc19uYW1lKHZhbHVlX3Zhcl9lbnEpDQogIA0KICBjYXQoIlxuIFN1bW1hcnkgc3RhdGlzdGljcyBcbiIpDQogIGRhdGEgJT4lDQogICAgZ3JvdXBfYnkoISF0aW1lX3Zhcl9lbnEpICU+JQ0KICAgIGdldF9zdW1tYXJ5X3N0YXRzKCEhdmFsdWVfdmFyX2VucSwgdHlwZSA9IGMoImNvbW1vbiIpKSAlPiUNCiAgICBwcmludCgpIA0KICANCiAgaWYoYXNzdW1fY2hlY2speyAgIyBUaGUgdGVzdCBhc3N1bWVzIHRoYXQgZGlmZmVyZW5jZXMgYmV0d2VlbiBwYWlyZWQgc2FtcGxlcyBzaG91bGQgYmUgZGlzdHJpYnV0ZWQgc3ltbWV0cmljYWxseSBhcm91bmQgdGhlIG1lZGlhbi4NCiAgZGF0YTIgPC0gDQogICAgZGF0YSAlPiUgDQogICAgZ3JvdXBfYnkoISFpZF92YXJfZW5xKSAlPiUgDQogICAgbXV0YXRlKGRpZmZlcmVuY2VzID0gISF2YWx1ZV92YXJfZW5xIC0gbGFnKCEhdmFsdWVfdmFyX2VucSkpDQoNCiAgaGlzdF9kaWZfcGxvdCA8LSBnZ2hpc3RvZ3JhbShkYXRhMiwgeCA9ICJkaWZmZXJlbmNlcyIsIHkgPSAiLi5kZW5zaXR5Li4iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsID0gInN0ZWVsYmx1ZSIsIGFkZF9kZW5zaXR5ID0gVFJVRSkNCiAgfQ0KICANCiAgY2F0KCJcbiBXaWxjb3hvbiBzaWduZWQgcmFuayB0ZXN0IG9uIHBhaXJlZCBzYW1wbGVzIFxuIikNCiAgc3RhdF90ZXN0IDwtIA0KICAgIGRhdGEgICU+JQ0KICAgIHdpbGNveF90ZXN0KGFzLmZvcm11bGEocGFzdGUwKHZhbHVlX3Zhcl9uYW1lLCAiIH4gIiwgdGltZV92YXJfbmFtZSkpLCANCiAgICAgICAgICAgICAgICBwYWlyZWQgPSBUUlVFKSAlPiUNCiAgICBhZGRfc2lnbmlmaWNhbmNlKCkNCiAgc3RhdF90ZXN0ICU+JSBwcmludCgpDQogIA0KICBjYXQoIlxuIEVmZmVjdCBzaXplIFxuIikNCiAgZWZfc2l6ZSA8LQ0KICAgIGRhdGEgJT4lDQogICAgd2lsY294X2VmZnNpemUoYXMuZm9ybXVsYShwYXN0ZTAodmFsdWVfdmFyX25hbWUsICIgfiAiLCB0aW1lX3Zhcl9uYW1lKSksIA0KICAgICAgICAgICAgICAgICAgIHBhaXJlZCA9IFRSVUUpDQogIGVmX3NpemUgJT4lIHByaW50KCkNCiAgDQogICMgVmlzdWFsaXphdGlvbg0KICBieF9wbG90IDwtIGdncGFpcmVkKGRhdGEsIHggPSB0aW1lX3Zhcl9uYW1lLCB5ID0gdmFsdWVfdmFyX25hbWUsIGlkID0gaWRfdmFyX25hbWUsDQogICAgICAgICAgICAgICAgICAgICAgeWxhYiA9IHZhbHVlX3Zhcl9uYW1lLCB4bGFiID0gdGltZV92YXJfbmFtZSkNCiAgDQogIHN0YXRfdGVzdCA8LSANCiAgICBzdGF0X3Rlc3QgJT4lIA0KICAgIGFkZF94eV9wb3NpdGlvbih4ID0gdGltZV92YXJfbmFtZSkNCiAgDQogIGJ4X3Bsb3QgPC0NCiAgICBieF9wbG90ICsgDQogICAgICBzdGF0X3B2YWx1ZV9tYW51YWwoc3RhdF90ZXN0LCB0aXAubGVuZ3RoID0gMCkgKw0KICAgICAgbGFicyhzdWJ0aXRsZSA9IGdldF90ZXN0X2xhYmVsKHN0YXRfdGVzdCwgZGV0YWlsZWQgPSBUUlVFKSkNCiAgDQogIGlmKGFzc3VtX2NoZWNrKXsgDQogICAgbGlzdChoaXN0X2RpZl9wbG90LCBieF9wbG90KQ0KICB9ZWxzZXsNCiAgICBieF9wbG90DQogIH0gIA0KICANCn0NCmBgYA0KDQoNCiMgcm1BTk9WQSBPWFQNCg0KYGBge3Igcm1BTk9WQV9veHQsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEwfQ0KY2F0KCIjIyBBbGwgc3ViamVjdHMiKQ0KRGF0YV9HZW5fbWVyZ2VkX2xvbmcgJT4lDQogIHNlbGVjdChJRCwgVmFycywgUHJlUG9zdCwgQ29uZCwgVmFscykgJT4lDQogIGZpbHRlcihWYXJzID09ICJPeCIpICU+JQ0KICBkcGx5cjo6cmVuYW1lKE9YVCA9IFZhbHMpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUgDQogIGZpbHRlcihuKCkgPiAzKSAlPiUgICAgICAgICAgICAgICAgICAgICAjIGZvciBjb21wbGV0ZSBjYXNlcw0KICB1bmdyb3VwKCkgJT4lDQogIHR3X3JtQU5PVkFfZnVuYyhpZF92YXIgPSBJRCwgY29uZF92YXIgPSBDb25kLCB0aW1lX3ZhciA9IFByZVBvc3QsIHZhbHVlX3ZhciA9IE9YVCwgDQogICAgICAgICAgICAgICAgICBwb3N0aG9jX3NpZ19pbnRlcmFjID0gVFJVRSwgcG9zdGhvY19uc19pbnRlcmFjID0gVFJVRSkNCg0KY2F0KCIjIyBGZW1hbGVzIikNCkRhdGFfZmVtICU+JQ0KICBzZWxlY3QoSUQsIFZhcnMsIFByZVBvc3QsIENvbmQsIFZhbHMpICU+JQ0KICBmaWx0ZXIoVmFycyA9PSAiT3giKSAlPiUNCiAgZHBseXI6OnJlbmFtZShPWFQgPSBWYWxzKSAlPiUNCiAgZHJvcF9uYSgpICU+JQ0KICBncm91cF9ieShJRCkgJT4lIA0KICBmaWx0ZXIobigpID4gMykgJT4lICAgICAgICAgICAgICAgICAgICAgIyBmb3IgY29tcGxldGUgY2FzZXMNCiAgdW5ncm91cCgpICU+JQ0KICB0d19ybUFOT1ZBX2Z1bmMoaWRfdmFyID0gSUQsIGNvbmRfdmFyID0gQ29uZCwgdGltZV92YXIgPSBQcmVQb3N0LCB2YWx1ZV92YXIgPSBPWFQsIA0KICAgICAgICAgICAgICAgICAgcG9zdGhvY19zaWdfaW50ZXJhYyA9IFRSVUUsIHBvc3Rob2NfbnNfaW50ZXJhYyA9IFRSVUUpDQoNCmNhdCgiIyMgTWFsZXMiKQ0KRGF0YV9tYXNjICU+JQ0KICBzZWxlY3QoSUQsIFZhcnMsIFByZVBvc3QsIENvbmQsIFZhbHMpICU+JQ0KICBmaWx0ZXIoVmFycyA9PSAiT3giKSAlPiUNCiAgZHBseXI6OnJlbmFtZShPWFQgPSBWYWxzKSAlPiUNCiAgZHJvcF9uYSgpICU+JQ0KICBncm91cF9ieShJRCkgJT4lIA0KICBmaWx0ZXIobigpID4gMykgJT4lICAgICAgICAgICAgICAgICAgICAgIyBmb3IgY29tcGxldGUgY2FzZXMNCiAgdW5ncm91cCgpICU+JQ0KICB0d19ybUFOT1ZBX2Z1bmMoaWRfdmFyID0gSUQsIGNvbmRfdmFyID0gQ29uZCwgdGltZV92YXIgPSBQcmVQb3N0LCB2YWx1ZV92YXIgPSBPWFQsIA0KICAgICAgICAgICAgICAgICAgcG9zdGhvY19zaWdfaW50ZXJhYyA9IFRSVUUsIHBvc3Rob2NfbnNfaW50ZXJhYyA9IFRSVUUpDQpgYGANCg0KIyBybUFOT1ZBIFN0cmVzDQoNCmBgYHtyIHJtQU5PVkFfc3RyZXMsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEwfQ0KY2F0KCIjIyBBbGwgc3ViamVjdHMiKQ0KRGF0YV9HZW5fbWVyZ2VkX2xvbmcgJT4lDQogIHNlbGVjdChJRCwgVmFycywgUHJlUG9zdCwgQ29uZCwgVmFscykgJT4lDQogIGZpbHRlcihWYXJzID09ICJWYXNTIikgJT4lDQogIGRwbHlyOjpyZW5hbWUoVmFzUyA9IFZhbHMpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUgDQogIGZpbHRlcihuKCkgPiAzKSAlPiUgICAgICAgICAgICAgICAgICAgICAjIGZvciBjb21wbGV0ZSBjYXNlcw0KICB1bmdyb3VwKCkgJT4lDQogIHR3X3JtQU5PVkFfZnVuYyhpZF92YXIgPSBJRCwgY29uZF92YXIgPSBDb25kLCB0aW1lX3ZhciA9IFByZVBvc3QsIHZhbHVlX3ZhciA9IFZhc1MsIA0KICAgICAgICAgICAgICAgICAgcG9zdGhvY19zaWdfaW50ZXJhYyA9IFRSVUUsIHBvc3Rob2NfbnNfaW50ZXJhYyA9IFRSVUUpDQoNCmNhdCgiIyMgRmVtYWxlcyIpDQpEYXRhX2ZlbSAlPiUNCiAgc2VsZWN0KElELCBWYXJzLCBQcmVQb3N0LCBDb25kLCBWYWxzKSAlPiUNCiAgZmlsdGVyKFZhcnMgPT0gIlZhc1MiKSAlPiUNCiAgZHBseXI6OnJlbmFtZShWYXNTID0gVmFscykgJT4lDQogIGRyb3BfbmEoKSAlPiUNCiAgZ3JvdXBfYnkoSUQpICU+JSANCiAgZmlsdGVyKG4oKSA+IDMpICU+JSAgICAgICAgICAgICAgICAgICAgICMgZm9yIGNvbXBsZXRlIGNhc2VzDQogIHVuZ3JvdXAoKSAlPiUNCiAgdHdfcm1BTk9WQV9mdW5jKGlkX3ZhciA9IElELCBjb25kX3ZhciA9IENvbmQsIHRpbWVfdmFyID0gUHJlUG9zdCwgdmFsdWVfdmFyID0gVmFzUywgDQogICAgICAgICAgICAgICAgICBwb3N0aG9jX3NpZ19pbnRlcmFjID0gVFJVRSwgcG9zdGhvY19uc19pbnRlcmFjID0gVFJVRSkNCg0KY2F0KCIjIyBNYWxlcyIpDQpEYXRhX21hc2MgJT4lDQogIHNlbGVjdChJRCwgVmFycywgUHJlUG9zdCwgQ29uZCwgVmFscykgJT4lDQogIGZpbHRlcihWYXJzID09ICJWYXNTIikgJT4lDQogIGRwbHlyOjpyZW5hbWUoVmFzUyA9IFZhbHMpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUgDQogIGZpbHRlcihuKCkgPiAzKSAlPiUgICAgICAgICAgICAgICAgICAgICAjIGZvciBjb21wbGV0ZSBjYXNlcw0KICB1bmdyb3VwKCkgJT4lDQogIHR3X3JtQU5PVkFfZnVuYyhpZF92YXIgPSBJRCwgY29uZF92YXIgPSBDb25kLCB0aW1lX3ZhciA9IFByZVBvc3QsIHZhbHVlX3ZhciA9IFZhc1MsIA0KICAgICAgICAgICAgICAgICAgcG9zdGhvY19zaWdfaW50ZXJhYyA9IFRSVUUsIHBvc3Rob2NfbnNfaW50ZXJhYyA9IFRSVUUpDQpgYGANCg0KIyBybUFOT1ZBIFdCDQoNCmBgYHtyIHJtQU5PVkFfd2IsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEwfQ0KY2F0KCIjIyBBbGwgc3ViamVjdHMiKQ0KRGF0YV9HZW5fbWVyZ2VkX2xvbmcgJT4lDQogIHNlbGVjdChJRCwgVmFycywgUHJlUG9zdCwgQ29uZCwgVmFscykgJT4lDQogIGZpbHRlcihWYXJzID09ICJWYXNCIikgJT4lDQogIGRwbHlyOjpyZW5hbWUoVmFzQiA9IFZhbHMpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUgDQogIGZpbHRlcihuKCkgPiAzKSAlPiUgICAgICAgICAgICAgICAgICAgICAjIGZvciBjb21wbGV0ZSBjYXNlcw0KICB1bmdyb3VwKCkgJT4lDQogIHR3X3JtQU5PVkFfZnVuYyhpZF92YXIgPSBJRCwgY29uZF92YXIgPSBDb25kLCB0aW1lX3ZhciA9IFByZVBvc3QsIHZhbHVlX3ZhciA9IFZhc0IsIA0KICAgICAgICAgICAgICAgICAgcG9zdGhvY19zaWdfaW50ZXJhYyA9IFRSVUUsIHBvc3Rob2NfbnNfaW50ZXJhYyA9IFRSVUUpDQoNCmNhdCgiIyMgRmVtYWxlcyIpDQpEYXRhX2ZlbSAlPiUNCiAgc2VsZWN0KElELCBWYXJzLCBQcmVQb3N0LCBDb25kLCBWYWxzKSAlPiUNCiAgZmlsdGVyKFZhcnMgPT0gIlZhc0IiKSAlPiUNCiAgZHBseXI6OnJlbmFtZShWYXNCID0gVmFscykgJT4lDQogIGRyb3BfbmEoKSAlPiUNCiAgZ3JvdXBfYnkoSUQpICU+JSANCiAgZmlsdGVyKG4oKSA+IDMpICU+JSAgICAgICAgICAgICAgICAgICAgICMgZm9yIGNvbXBsZXRlIGNhc2VzDQogIHVuZ3JvdXAoKSAlPiUNCiAgdHdfcm1BTk9WQV9mdW5jKGlkX3ZhciA9IElELCBjb25kX3ZhciA9IENvbmQsIHRpbWVfdmFyID0gUHJlUG9zdCwgdmFsdWVfdmFyID0gVmFzQiwgDQogICAgICAgICAgICAgICAgICBwb3N0aG9jX3NpZ19pbnRlcmFjID0gVFJVRSwgcG9zdGhvY19uc19pbnRlcmFjID0gVFJVRSkNCg0KY2F0KCIjIyBNYWxlcyIpDQpEYXRhX21hc2MgJT4lDQogIHNlbGVjdChJRCwgVmFycywgUHJlUG9zdCwgQ29uZCwgVmFscykgJT4lDQogIGZpbHRlcihWYXJzID09ICJWYXNCIikgJT4lDQogIGRwbHlyOjpyZW5hbWUoVmFzQiA9IFZhbHMpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUgDQogIGZpbHRlcihuKCkgPiAzKSAlPiUgICAgICAgICAgICAgICAgICAgICAjIGZvciBjb21wbGV0ZSBjYXNlcw0KICB1bmdyb3VwKCkgJT4lDQogIHR3X3JtQU5PVkFfZnVuYyhpZF92YXIgPSBJRCwgY29uZF92YXIgPSBDb25kLCB0aW1lX3ZhciA9IFByZVBvc3QsIHZhbHVlX3ZhciA9IFZhc0IsIA0KICAgICAgICAgICAgICAgICAgcG9zdGhvY19zaWdfaW50ZXJhYyA9IFRSVUUsIHBvc3Rob2NfbnNfaW50ZXJhYyA9IFRSVUUpDQpgYGANCg0KDQoNCiMgV2lsY294b24gcGFpcmVkIG9uIE9yZGVyIG9mIENvbmRpdGlvbnMgLSBPWFQNCg0KYGBge3Igd2lsbGNveG9uX294dF9vcmRlciwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OH0NCmNhdCgiIyMgV2hvbGUgU2FtcGxlIC0gUG96IGZpcnN0LCBOZWcgc2Vjb25kIikNCkRhdGFfR2VuX21lcmdlZF9sb25nICU+JQ0KICBzZWxlY3QoSUQsIFZhcnMsIFByZVBvc3QsIENvbmQsIFZhbHMsIEV4ZXJjaXRpdWwpICU+JQ0KICBmaWx0ZXIoRXhlcmNpdGl1bCA9PSAiUG96aXRpdiAtIE5lZ2F0aXYiKSAlPiUNCiAgZmlsdGVyKFZhcnMgPT0gIk94IikgJT4lDQogIGRwbHlyOjpyZW5hbWUoT1hUID0gVmFscykgJT4lDQogIGRyb3BfbmEoKSAlPiUNCiAgZ3JvdXBfYnkoSUQpICU+JSANCiAgZmlsdGVyKG4oKSA+IDMpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIHdpbGNveG9uX3BhaXJlZF9mdW5jKGlkX3ZhciA9IElELCB0aW1lX3ZhciA9IFByZVBvc3QsIHZhbHVlX3ZhciA9IE9YVCwgYXNzdW1fY2hlY2sgPSBUUlVFKQ0KDQpjYXQoIiMjIFdob2xlIFNhbXBsZSAtIE5lZyBmaXJzdCwgUG96IHNlY29uZCIpDQpEYXRhX0dlbl9tZXJnZWRfbG9uZyAlPiUNCiAgc2VsZWN0KElELCBWYXJzLCBQcmVQb3N0LCBDb25kLCBWYWxzLCBFeGVyY2l0aXVsKSAlPiUNCiAgZmlsdGVyKEV4ZXJjaXRpdWwgPT0gIk5lZ2F0aXYgLSBQb3ppdGl2IikgJT4lDQogIGZpbHRlcihWYXJzID09ICJPeCIpICU+JQ0KICBkcGx5cjo6cmVuYW1lKE9YVCA9IFZhbHMpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUgDQogIGZpbHRlcihuKCkgPiAzKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICB3aWxjb3hvbl9wYWlyZWRfZnVuYyhpZF92YXIgPSBJRCwgdGltZV92YXIgPSBQcmVQb3N0LCB2YWx1ZV92YXIgPSBPWFQsIGFzc3VtX2NoZWNrID0gVFJVRSkNCg0KDQoNCmNhdCgiIyMgRmVtYWxlcyAtIFBveiBmaXJzdCwgTmVnIHNlY29uZCIpDQpEYXRhX2ZlbSAlPiUNCiAgc2VsZWN0KElELCBWYXJzLCBQcmVQb3N0LCBDb25kLCBWYWxzLCBFeGVyY2l0aXVsKSAlPiUNCiAgZmlsdGVyKEV4ZXJjaXRpdWwgPT0gIlBveml0aXYgLSBOZWdhdGl2IikgJT4lDQogIGZpbHRlcihWYXJzID09ICJPeCIpICU+JQ0KICBkcGx5cjo6cmVuYW1lKE9YVCA9IFZhbHMpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUgDQogIGZpbHRlcihuKCkgPiAzKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICB3aWxjb3hvbl9wYWlyZWRfZnVuYyhpZF92YXIgPSBJRCwgdGltZV92YXIgPSBQcmVQb3N0LCB2YWx1ZV92YXIgPSBPWFQsIGFzc3VtX2NoZWNrID0gVFJVRSkNCg0KY2F0KCIjIyBGZW1hbGVzIC0gTmVnIGZpcnN0LCBQb3ogc2Vjb25kIikNCkRhdGFfZmVtICU+JQ0KICBzZWxlY3QoSUQsIFZhcnMsIFByZVBvc3QsIENvbmQsIFZhbHMsIEV4ZXJjaXRpdWwpICU+JQ0KICBmaWx0ZXIoRXhlcmNpdGl1bCA9PSAiTmVnYXRpdiAtIFBveml0aXYiKSAlPiUNCiAgZmlsdGVyKFZhcnMgPT0gIk94IikgJT4lDQogIGRwbHlyOjpyZW5hbWUoT1hUID0gVmFscykgJT4lDQogIGRyb3BfbmEoKSAlPiUNCiAgZ3JvdXBfYnkoSUQpICU+JSANCiAgZmlsdGVyKG4oKSA+IDMpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIHdpbGNveG9uX3BhaXJlZF9mdW5jKGlkX3ZhciA9IElELCB0aW1lX3ZhciA9IFByZVBvc3QsIHZhbHVlX3ZhciA9IE9YVCwgYXNzdW1fY2hlY2sgPSBUUlVFKQ0KDQpgYGANCg0KIyBXaWxjb3hvbiBwYWlyZWQgb24gT3JkZXIgb2YgQ29uZGl0aW9ucyAtIFN0cmVzDQoNCmBgYHtyIHdpbGxjb3hvbl9zdHJlc19vcmRlciwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OH0NCmNhdCgiIyMgV2hvbGUgU2FtcGxlIC0gUG96IGZpcnN0LCBOZWcgc2Vjb25kIikNCkRhdGFfR2VuX21lcmdlZF9sb25nICU+JQ0KICBzZWxlY3QoSUQsIFZhcnMsIFByZVBvc3QsIENvbmQsIFZhbHMsIEV4ZXJjaXRpdWwpICU+JQ0KICBmaWx0ZXIoRXhlcmNpdGl1bCA9PSAiUG96aXRpdiAtIE5lZ2F0aXYiKSAlPiUNCiAgZmlsdGVyKFZhcnMgPT0gIlZhc1MiKSAlPiUNCiAgZHBseXI6OnJlbmFtZShWYXNTID0gVmFscykgJT4lDQogIGRyb3BfbmEoKSAlPiUNCiAgZ3JvdXBfYnkoSUQpICU+JSANCiAgZmlsdGVyKG4oKSA+IDMpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIHdpbGNveG9uX3BhaXJlZF9mdW5jKGlkX3ZhciA9IElELCB0aW1lX3ZhciA9IFByZVBvc3QsIHZhbHVlX3ZhciA9IFZhc1MsIGFzc3VtX2NoZWNrID0gVFJVRSkNCg0KY2F0KCIjIyBXaG9sZSBTYW1wbGUgLSBOZWcgZmlyc3QsIFBveiBzZWNvbmQiKQ0KRGF0YV9HZW5fbWVyZ2VkX2xvbmcgJT4lDQogIHNlbGVjdChJRCwgVmFycywgUHJlUG9zdCwgQ29uZCwgVmFscywgRXhlcmNpdGl1bCkgJT4lDQogIGZpbHRlcihFeGVyY2l0aXVsID09ICJOZWdhdGl2IC0gUG96aXRpdiIpICU+JQ0KICBmaWx0ZXIoVmFycyA9PSAiVmFzUyIpICU+JQ0KICBkcGx5cjo6cmVuYW1lKFZhc1MgPSBWYWxzKSAlPiUNCiAgZHJvcF9uYSgpICU+JQ0KICBncm91cF9ieShJRCkgJT4lIA0KICBmaWx0ZXIobigpID4gMykgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgd2lsY294b25fcGFpcmVkX2Z1bmMoaWRfdmFyID0gSUQsIHRpbWVfdmFyID0gUHJlUG9zdCwgdmFsdWVfdmFyID0gVmFzUywgYXNzdW1fY2hlY2sgPSBUUlVFKQ0KDQoNCg0KY2F0KCIjIyBGZW1hbGVzIC0gUG96IGZpcnN0LCBOZWcgc2Vjb25kIikNCkRhdGFfZmVtICU+JQ0KICBzZWxlY3QoSUQsIFZhcnMsIFByZVBvc3QsIENvbmQsIFZhbHMsIEV4ZXJjaXRpdWwpICU+JQ0KICBmaWx0ZXIoRXhlcmNpdGl1bCA9PSAiUG96aXRpdiAtIE5lZ2F0aXYiKSAlPiUNCiAgZmlsdGVyKFZhcnMgPT0gIlZhc1MiKSAlPiUNCiAgZHBseXI6OnJlbmFtZShWYXNTID0gVmFscykgJT4lDQogIGRyb3BfbmEoKSAlPiUNCiAgZ3JvdXBfYnkoSUQpICU+JSANCiAgZmlsdGVyKG4oKSA+IDMpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIHdpbGNveG9uX3BhaXJlZF9mdW5jKGlkX3ZhciA9IElELCB0aW1lX3ZhciA9IFByZVBvc3QsIHZhbHVlX3ZhciA9IFZhc1MsIGFzc3VtX2NoZWNrID0gVFJVRSkNCg0KY2F0KCIjIyBGZW1hbGVzIC0gTmVnIGZpcnN0LCBQb3ogc2Vjb25kIikNCkRhdGFfZmVtICU+JQ0KICBzZWxlY3QoSUQsIFZhcnMsIFByZVBvc3QsIENvbmQsIFZhbHMsIEV4ZXJjaXRpdWwpICU+JQ0KICBmaWx0ZXIoRXhlcmNpdGl1bCA9PSAiTmVnYXRpdiAtIFBveml0aXYiKSAlPiUNCiAgZmlsdGVyKFZhcnMgPT0gIlZhc1MiKSAlPiUNCiAgZHBseXI6OnJlbmFtZShWYXNTID0gVmFscykgJT4lDQogIGRyb3BfbmEoKSAlPiUNCiAgZ3JvdXBfYnkoSUQpICU+JSANCiAgZmlsdGVyKG4oKSA+IDMpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIHdpbGNveG9uX3BhaXJlZF9mdW5jKGlkX3ZhciA9IElELCB0aW1lX3ZhciA9IFByZVBvc3QsIHZhbHVlX3ZhciA9IFZhc1MsIGFzc3VtX2NoZWNrID0gVFJVRSkNCmBgYA0KDQoNCiMgV2lsY294b24gcGFpcmVkIG9uIE9yZGVyIG9mIENvbmRpdGlvbnMgLSBXQg0KDQpgYGB7ciB3aWxsY294b25fd2Jfb3JkZXIsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTh9DQpjYXQoIiMjIFdob2xlIFNhbXBsZSAtIFBveiBmaXJzdCwgTmVnIHNlY29uZCIpDQpEYXRhX0dlbl9tZXJnZWRfbG9uZyAlPiUNCiAgc2VsZWN0KElELCBWYXJzLCBQcmVQb3N0LCBDb25kLCBWYWxzLCBFeGVyY2l0aXVsKSAlPiUNCiAgZmlsdGVyKEV4ZXJjaXRpdWwgPT0gIlBveml0aXYgLSBOZWdhdGl2IikgJT4lDQogIGZpbHRlcihWYXJzID09ICJWYXNCIikgJT4lDQogIGRwbHlyOjpyZW5hbWUoVmFzQiA9IFZhbHMpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUgDQogIGZpbHRlcihuKCkgPiAzKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICB3aWxjb3hvbl9wYWlyZWRfZnVuYyhpZF92YXIgPSBJRCwgdGltZV92YXIgPSBQcmVQb3N0LCB2YWx1ZV92YXIgPSBWYXNCLCBhc3N1bV9jaGVjayA9IFRSVUUpDQoNCmNhdCgiIyMgV2hvbGUgU2FtcGxlIC0gTmVnIGZpcnN0LCBQb3ogc2Vjb25kIikNCkRhdGFfR2VuX21lcmdlZF9sb25nICU+JQ0KICBzZWxlY3QoSUQsIFZhcnMsIFByZVBvc3QsIENvbmQsIFZhbHMsIEV4ZXJjaXRpdWwpICU+JQ0KICBmaWx0ZXIoRXhlcmNpdGl1bCA9PSAiTmVnYXRpdiAtIFBveml0aXYiKSAlPiUNCiAgZmlsdGVyKFZhcnMgPT0gIlZhc0IiKSAlPiUNCiAgZHBseXI6OnJlbmFtZShWYXNCID0gVmFscykgJT4lDQogIGRyb3BfbmEoKSAlPiUNCiAgZ3JvdXBfYnkoSUQpICU+JSANCiAgZmlsdGVyKG4oKSA+IDMpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIHdpbGNveG9uX3BhaXJlZF9mdW5jKGlkX3ZhciA9IElELCB0aW1lX3ZhciA9IFByZVBvc3QsIHZhbHVlX3ZhciA9IFZhc0IsIGFzc3VtX2NoZWNrID0gVFJVRSkNCg0KDQoNCmNhdCgiIyMgRmVtYWxlcyAtIFBveiBmaXJzdCwgTmVnIHNlY29uZCIpDQpEYXRhX2ZlbSAlPiUNCiAgc2VsZWN0KElELCBWYXJzLCBQcmVQb3N0LCBDb25kLCBWYWxzLCBFeGVyY2l0aXVsKSAlPiUNCiAgZmlsdGVyKEV4ZXJjaXRpdWwgPT0gIlBveml0aXYgLSBOZWdhdGl2IikgJT4lDQogIGZpbHRlcihWYXJzID09ICJWYXNCIikgJT4lDQogIGRwbHlyOjpyZW5hbWUoVmFzQiA9IFZhbHMpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUgDQogIGZpbHRlcihuKCkgPiAzKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICB3aWxjb3hvbl9wYWlyZWRfZnVuYyhpZF92YXIgPSBJRCwgdGltZV92YXIgPSBQcmVQb3N0LCB2YWx1ZV92YXIgPSBWYXNCLCBhc3N1bV9jaGVjayA9IFRSVUUpDQoNCmNhdCgiIyMgRmVtYWxlcyAtIE5lZyBmaXJzdCwgUG96IHNlY29uZCIpDQpEYXRhX2ZlbSAlPiUNCiAgc2VsZWN0KElELCBWYXJzLCBQcmVQb3N0LCBDb25kLCBWYWxzLCBFeGVyY2l0aXVsKSAlPiUNCiAgZmlsdGVyKEV4ZXJjaXRpdWwgPT0gIk5lZ2F0aXYgLSBQb3ppdGl2IikgJT4lDQogIGZpbHRlcihWYXJzID09ICJWYXNCIikgJT4lDQogIGRwbHlyOjpyZW5hbWUoVmFzQiA9IFZhbHMpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUgDQogIGZpbHRlcihuKCkgPiAzKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICB3aWxjb3hvbl9wYWlyZWRfZnVuYyhpZF92YXIgPSBJRCwgdGltZV92YXIgPSBQcmVQb3N0LCB2YWx1ZV92YXIgPSBWYXNCLCBhc3N1bV9jaGVjayA9IFRSVUUpDQpgYGANCg0KDQoNCjxicj4NCg0KDQoNCjwhLS0gU2Vzc2lvbiBJbmZvIGFuZCBMaWNlbnNlIC0tPg0KDQo8YnI+DQoNCiMgU2Vzc2lvbiBJbmZvDQpgYGB7ciBzZXNzaW9uX2luZm8sIGVjaG8gPSBGQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQ0Kc2Vzc2lvbkluZm8oKSAgICANCmBgYA0KDQo8IS0tIEZvb3RlciAtLT4NCiZuYnNwOw0KPGhyIC8+DQo8cCBzdHlsZT0idGV4dC1hbGlnbjogY2VudGVyOyI+QSB3b3JrIGJ5IDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9DbGF1ZGl1UGFwYXN0ZXJpLyI+Q2xhdWRpdSBQYXBhc3Rlcmk8L2E+PC9wPg0KPHAgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPjxzcGFuIHN0eWxlPSJjb2xvcjogIzgwODA4MDsiPjxlbT5jbGF1ZGl1LnBhcGFzdGVyaUBnbWFpbC5jb208L2VtPjwvc3Bhbj48L3A+DQombmJzcDsNCg==